﻿#include "Player.h"
#include <math.h>
#define CONTRA_VX 2.2f 
#define TIME 1000.0f / 60.0f 
#define DELAY 360
#define R_BULLET R
#define V_JUMP 8.5f
#include "ShareComponents.h"
#include"RSManager.h"
#include "Sprite.h"
#include "FWKeyboard.h"
#include "Camera.h"
#include "Box.h"
#include "PlayerState.h"
#include "OnSpaceState.h"
#include "OnGroundState.h"
#include "OnWaterState.h"
#include "BulletManager.h"
#include "StaticObject.h"
#include "Map.h"

Player::Player(Box* box): Object(box, ObjPlayer), MoveObject()
{	
	_bulletID = B_S;
	this->delay = 0;
	_remainTime = DELAY;
	_isAlive = true;
	_hits = 1000;
	_onGroundState = new OnGroundState(this);
	_onSpaceState = new OnSpaceState(this);
	_onWaterState = new OnWaterState(this);	
	_dieLeft = RSManager::getInstance()->getSprite(PLAYER_DIE_LEFT);
	_dieRight = RSManager::getInstance()->getSprite(PLAYER_DIE_RIGHT);
	_state = _onSpaceState;
	_enumState = ONSPACE;
	_preState = ONSPACE;
	this->AssignMove(this->_box);
	gl_player = _box;
	_endOfWorld = gl_map->getEndWorld().x;
}

Player::~Player()
{

}

void Player::update()
{
	if(_isAlive)
	{
		gl_player = _box;
		gl_ground_player = _getBoundBox();
		gl_move = _getMoveBox();
		//Next frame
		this->delay += TIME;
		if (delay > 85)
		{
			delay = 0;		
			_sprite->Next();
		}

		switch (_enumState)
		{
		case ONGROUND:
			gl_ground = _getGround();
			_state = _onGroundState;
			if(_preState == ONWATER)
				_state->setDirection(_onWaterState->getJumpDirection(), _onWaterState->getGoDirection());
			if(_preState == ONSPACE)
				_state->setDirection(_onSpaceState->getJumpDirection(), _onSpaceState->getGoDirection());
			_preState = ONGROUND;
			if(_getCurrentGround() == NULL)
			{
				_onGroundState->setJumpDirection(DOWN);
				_state = _onSpaceState;
			}
			else
				if(_getCurrentGround()->getID() == WATER)
					_state = _onWaterState;
			break;
		case ONSPACE:
			_state = _onSpaceState;
			if(_preState == ONGROUND)
			{			
				_onSpaceState->jump(_onGroundState->getJumpDirection(), _onGroundState->getGoDirection());			
			}
			_preState = ONSPACE;
			if(isOnGround() && _box->_v.y < 0)
			{
				_state->setDirection(_onSpaceState->getJumpDirection(), _onSpaceState->getGoDirection());
				_state = _onGroundState;
				RSManager::getInstance()->playMusic(LANDING);
			}		
			if(isOnWater())
			{
				_state = _onWaterState;
				RSManager::getInstance()->playMusic(LANDING);
			}
			break;
		case ONWATER:
			_state = _onWaterState;
			if(_preState == ONGROUND)
				_state->setDirection(_onGroundState->getJumpDirection(), _onGroundState->getGoDirection());
			if(_preState == ONSPACE)
				_state->setDirection(_onSpaceState->getJumpDirection(), _onSpaceState->getGoDirection());
			_preState = ONWATER;
			if(!isOnWater())
				_state = _onGroundState;
			break;
		default:
			break;
		}		
		_enumState = _state->handleInput(TIME);

		if(_box->_position.y <= gl_camera->getTop() - 32 || _hits <= 0 && _isAlive)
		{			
			if (_state->getGoDirection() == LEFT)
			{
				_sprite = _dieLeft;
				set_vx(CONTRA_VX);
			}
			else
			{
				_sprite = _dieRight;
				set_vx(-CONTRA_VX);
			}
			jumpUp(5);
			_remainTime = 0;
			_isAlive = false;	
			RSManager::getInstance()->playMusic(PLAYER_DIE);
		}
	}
	else
		goDie();


	setPlayerBox();

	this->move();	

}
void Player::render()
{			
	_sprite->Render(_box->_position);	
}


void Player::setPlayerBox()
{
	_box->_size = _sprite->getRenderSize();	
	//_box->_size.y /= 2;	
}

Box* Player::getPlayerBox()
{
	return _box;
}

void Player::setSprite(Sprite* s)
{
	_sprite = s;
}

void Player::jumpUp()
{
	_box->_v.y = V_JUMP;
}

void Player::jumpUp(float h)
{
	_box->_v.y = h;
}

void Player::jumpDown()
{
	if(canFallDown())
		this->fallDown();
}


void Player::set_vx(float vx)
{
	Box* b = gl_camera->getBox();
	if((_box->_position.x >=  b->getLeft() + 5 && vx < 0) || (_box->_position.x <= _endOfWorld && vx > 0))
		_box->_v.x = vx;
	else _box->_v.x = 0;
}

void Player::setState(PlayerState* state)
{
	_state = state;
}

void Player::setBulletID(BULLET_ID b)
{
	_bulletID = b;
}

BULLET_ID Player::getBulletID()
{
	return _bulletID;
}

void Player::shoot(int pos_x, int pos_y, float angle)
{
	BulletManager::getInstance()->shoot(_bulletID, _obj, _box->_position + D3DXVECTOR2(pos_x, pos_y), angle);
}

Box* Player::getCollisionBox()
{
	return _colBox;	
}

void Player::setCollisionBox(Box* box)
{
	_colBox = box;
}

bool Player::isAlive()
{
	return _isAlive;
}

void Player::goDie()
{	
	_remainTime += GAME_TIME;
	if(_remainTime >= 80)
	{
		_remainTime = 0;
		if(_sprite->GetCurrentIndex() != 4)					
			_sprite->Next();		
		else
			set_vx(0);
	}
}
